using Engine.Graphics;
using Game;

namespace SCIENEW {
    /// <summary>
    /// 流体系统（类方块系统）的管理器
    /// </summary>
    public static class FluidsManager {
        public static Fluid[] Fluids;

        public static Dictionary<string, int[]> IdMap = new();

        /// <summary>
        /// 流体于方块的对应关系，第一个是流体，第二个是方块
        /// </summary>
        public static BiDictionary<int, int> FluidToBlock = new();

        static Texture2D m_normalFluidTexture;

        public static Texture2D NormalFluidTexture {
            get {
                if (m_normalFluidTexture == null) {
                    m_normalFluidTexture = ContentManager.Get<Texture2D>("Textures/NormalFluid");
                }
                return m_normalFluidTexture;
            }
        }

        public static void Init() {
            Fluids = [
                new AirFluid(),
                new WaterFluid(),
                new MagmaFluid(),
                new MoltenMetalFluid(Materials.Steel),
                new MoltenMetalFluid(Materials.Gold),
                new MoltenMetalFluid(Materials.Silver),
                new MoltenMetalFluid(Materials.Lead),
                new MoltenMetalFluid(Materials.Platinum),
                new MoltenMetalFluid(Materials.Zinc),
                new MoltenMetalFluid(Materials.Stannary),
                new MoltenMetalFluid(Materials.Chromium),
                new MoltenMetalFluid(Materials.Titanium),
                new MoltenMetalFluid(Materials.Nickel),
                new MoltenMetalFluid(Materials.Aluminum),
                new MoltenMetalFluid(Materials.Iron),
                new MoltenMetalFluid(Materials.Copper),
                new MoltenMetalFluid(Materials.Germanium),
                new MoltenMetalFluid(Materials.FeAlCrAlloy),
                new MoltenMetalFluid(Materials.Brass),
                new MoltenMetalFluid(Materials.Vanadium),
                new MoltenMetalFluid(Materials.Cupronickel),
            ];

            int index = 0;
            foreach (var fluid in Fluids) {
                //ID
                int[] fluidIndices = new int[fluid.GetCongenericFluidCount()];
                for (int i = 0; i < fluid.GetCongenericFluidCount(); i++) {
                    int fluidID = SetFluidValue(index, i);
                    fluidIndices[i] = fluidID;

                    //流体到方块
                    if (fluid is IPlaceableFluid placeableFluid) {
                        FluidToBlock.Add(fluidID, placeableFluid.GetFluidBlockIndex(fluidID));
                    }
                }
                IdMap.Add(fluid.GetCraftingID(fluidIndices[0]), fluidIndices);
                index++;
            }
        }

        public static int GetFluidIndex(int value) => value & 0xFFFF;//只取前16位

        public static int GetFluidData(int value) => (value >> 16) & 0xFFFF;//只取后16位

        public static int SetFluidValue(int index, int data) => ((data & 0xFFFF) << 16) | (index & 0XFFFF);

        public static Fluid GetFluid(int value) => Fluids[GetFluidIndex(value)];

        public static int GetFluidID(Fluid fluid) => IdMap.ElementAt(Fluids.FirstIndex(fluid)).Value[0];

        public static int GetFluidID(string id, int data) => IdMap[id][data];

        public static int GetFluidIDByMaterial<T>(Materials material) where T : Fluid {
            foreach (var fluid in Fluids) {
                if (fluid.GetType() != typeof(T)) continue;
                if (fluid is IMaterialBlock materialFluid
                    && materialFluid.GetMaterial() == material)
                    return GetFluidID(fluid);
            }
            return -1;
        }

        //TODO
        public static float GetContainerVolume(int value) => value is EmptyBucketBlock.Index or WaterBucketBlock.Index or MagmaBucketBlock.Index ? 4 : 0;
    }
}